package net.meosoft.maven.plugins;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;

/**
 * Creates junction points on a Windows environment.
 * @author Michael Sena (msena)
 */
public final class WinJunction {
	/** Location of the executable 'junction.exe' file. */
	private static final File EXECUTABLE = new File(ClassLoader.getSystemResource("junction.exe").getFile());

	/**
	 * Creates a junction point.
	 * @param link
	 *            Junction folder to create
	 * @param target
	 *            Where the junction will point to
	 * @throws IOException
	 *             when the junction could not be made
	 * @return output of the process
	 */
	public static String create(final File link, final File target) throws IOException {
		Process process = null;
		process = new ProcessBuilder(WinJunction.EXECUTABLE.toString(), link.getPath(), target.getPath()).start();
		return WinJunction.runProcessAndGetOutput(process);
	}

	/**
	 * Executes a process, returning the output.
	 * @param process
	 *            Process to execute
	 * @return output of the process
	 */
	private static String runProcessAndGetOutput(final Process process) {
		final StringBuilder output = new StringBuilder();

		try {
			final int code = process.waitFor();
			output.append("Process completed with code: ").append(code).append('\n');
		} catch (final InterruptedException e) {
			throw new RuntimeException("Junction process was interrupted before it could complete.", e);
		}

		final BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream(),
						Charset.defaultCharset()));
		try {
			while (br.ready()) {
				output.append(br.readLine()).append('\n');
			}
		} catch (final IOException e) {
			output.append('\n').append("Error reading stream: ").append(e);
		} finally {
			try {
				br.close();
			} catch (final IOException e) {
				output.append('\n').append("Unable to close stream: ").append(e);
			}
		}
		return output.toString();
	}

	/** Hide the constructor. */
	private WinJunction() {
		//
	}
}
